package com.whale.cloud.util.rest.query;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.whale.cloud.exception.CommonException;
import com.whale.cloud.util.StringUtils;
import com.whale.cloud.util.rest.condition.EColumnAuthority;
import com.whale.cloud.util.rest.dataengine.DataDisposeEngine;
import com.whale.cloud.util.rest.dataengine.LogicExpression;
import com.whale.cloud.util.rest.dataengine.OrganizeQuery;
import com.whale.cloud.util.rest.schema.Column;
import com.whale.cloud.util.rest.schema.Function;
import com.whale.cloud.util.rest.schema.FunctionManager;
import com.whale.cloud.util.rest.query.GetSysConfigure;
import com.whale.cloud.util.spring.SpringUtils;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Created by paco on 6/6/2017.
 */
@Log4j2
@Component
public class Query {
		/*@Autowired
		@Qualifier("mysqlDataEngine")
		*/
		DataDisposeEngine dataDisposeEngine;

		@Autowired
		private FunctionManager functionManager;

		public void setFunctionManager(FunctionManager tm) {
				this.functionManager = tm;
		}

		public JSONObject queryArray(JSONObject param) throws CommonException {
				JSONObject resultjo = new JSONObject(); //返回数据
				List<Column> user_columns = null; //用户字段权限
				List<Column> field_columns = null; //传入字段
				Function table = null; //数据表
				long userId = 0; //用户ID

				//region 参数判断
				//region 1、系统参数判断
				if (param == null || param.isEmpty()) {
						log.error("param is null");
						throw new CommonException("-1", "参数不能为空");
				}

				//endregion

				//region 2、获取用户信息
				if (!param.containsKey("user_id")) {
						log.error("param not has user_id,param;" + param.toJSONString());
						throw new CommonException("-3", "缺少用户信息");
				}

				userId = param.getLongValue("user_id");
				if (userId == 0) {
						log.error("param user_id error,param;" + param.toJSONString());
						throw new CommonException("-3", "缺少用户信息");
				}
				//endregion

				//region 3、业务参数判断
				if (!param.containsKey("function")) {
						log.error("data not has table key:" + param);
						throw new CommonException("-1", "业务参数错误");
				}

				String table_name = param.getString("function");
				if (StringUtils.isNull(table_name)) {
						log.error("data table is null:" + param);
						throw new CommonException("-1", "业务参数错误");
				}

				table = functionManager.getByName(table_name);
				if (table == null) {
						log.error("data table object is null:" + param);
						throw new CommonException("-1", "业务参数错误");
				}

				//获取数据处理的对句
				dataDisposeEngine = SpringUtils.getBean(table.getDataFrom() + "DataEngine");

				String fieldNames = param.getString("field");
				if (StringUtils.isNotNull(fieldNames)) {
						field_columns = table.getByDBNames(fieldNames);
				}
				//endregion

				//region 4、获取REDIS中的用户字段权限

				user_columns = table.getUserColumns(userId, EColumnAuthority.search);
				if (user_columns == null || user_columns.size() <= 0) {
						log.error("user_columns is null,param;" + param.toJSONString());
						throw new CommonException("-3", "用户权限不足");
				}

				//求出接口传入的查询字段与用户权限字段的交集

				//endregion
				//endregion

				//region 组织查询参数
				//region 1、提取有括号的内容
				OrganizeQuery qq = OrganizeQuery.getInstance();

				//endregion

				//region 2、根据第一步反推出表达式对象
				LogicExpression le = qq.setCondition(param.getString("condition"));
				//endregion

				//region 3、封装查询语句
				//IDataDisposeEngine de=new MysqlDataEngine();

				resultjo = dataDisposeEngine.getJSONArray(table, field_columns, le, param);
				//endregion
				//endregion

				return resultjo;
		}

		public JSONObject queryObject(JSONObject param) throws CommonException {
				JSONObject resultjo = new JSONObject(); //返回数据
				List<Column> user_columns = null; //用户字段权限
				//List<Column> field_columns = null; //传入字段
				List<String> field_columnname = null;
				List<Column> search_columns = new ArrayList<>();
				Function table = null; //数据表
				long userId = 0; //用户ID

				//region 参数判断
				//region 1、系统参数判断
				if (param == null || param.isEmpty()) {
						log.error("param is null");
						throw new CommonException("-1", "参数不能为空");
				}

				//endregion

				//region 2、获取用户信息
				if (!param.containsKey("user_id")) {
						log.error("param not has user_id,param;" + param.toJSONString());
						throw new CommonException("-3", "缺少用户信息");
				}

				userId = param.getLongValue("user_id");
				if (userId == 0) {
						log.error("param user_id error,param;" + param.toJSONString());
						throw new CommonException("-3", "缺少用户信息");
				}
				//endregion

				//region 3、业务参数判断
				if (!param.containsKey("function")) {
						log.error("data not has table key:" + param);
						throw new CommonException("-1", "业务参数错误");
				}

				String table_name = param.getString("function");
				if (StringUtils.isNull(table_name)) {
						log.error("data table is null:" + param);
						throw new CommonException("-1", "业务参数错误");
				}

				table = functionManager.getByName(table_name);
				if (table == null) {
						log.error("data table object is null:" + param);
						throw new CommonException("-1", "业务参数错误");
				}
				dataDisposeEngine = SpringUtils.getBean(table.getDataFrom() + "DataEngine");

				String fieldNames = param.getString("field");
				if (StringUtils.isNotNull(fieldNames)) {
						//field_columns = table.getByDBNames(fieldNames);
						String[] fs = fieldNames.split("\\s*,\\s*");
						field_columnname = Arrays.asList(fs);
				}
				//endregion
				EColumnAuthority e=EColumnAuthority.search;
				if (param.containsKey("authcode")){
					String authcode=param.getString("authcode");
					if ("1".equals(authcode)){
						e=EColumnAuthority.create;
					}
					if ("3".equals(authcode)){
						e=EColumnAuthority.modify;
					}
				}
				//region 4、获取REDIS中的用户字段权限
				user_columns = table.getUserColumns(userId, e);
				if (user_columns == null || user_columns.size() <= 0) {
						log.error("redis user_columns is null,param;" + param.toJSONString());
						throw new CommonException("-3", "用户权限不足");
				}

				//求出接口传入的查询字段与用户权限字段的交集
				int uclength = user_columns.size();
				for (Column c : user_columns) {
						if (field_columnname.contains(c.getDb_name())) {
								search_columns.add(c);
						}
				}

				//field_columns.intersect();//..Intersect();

				//endregion
				//endregion

				//region 组织查询参数
				//region 1、提取有括号的内容
				OrganizeQuery qq = OrganizeQuery.getInstance();

				//endregion

				//region 2、根据第一步反推出表达式对象
				LogicExpression le = qq.setCondition(param.getString("condition"));
				//endregion

				//region 3、封装查询语句
				//根据表数据来源作不同处理
				resultjo = dataDisposeEngine.getJSONObject(table, search_columns, le, param);
				//endregion
				//endregion
				return resultjo;
		}

		/**
		 * 获取用户字段权限
		 *
		 * @param function
		 * @param userId
		 * @param authCode
		 * @return
		 */
		public JSONArray queryUserColumns(String function, long userId, String authCode)
						throws CommonException {
				long functionId = 0;
				JSONArray userColumnja = null;
				if (StringUtils.isNull(function)) {
						return userColumnja;
				}
				//判断是否是ID
				if (StringUtils.isDigital(function)) {
						functionId = Long.valueOf(function);
				} else {
						Function fun = functionManager.getByName(function);
						functionId = fun.getId();
				}
				GetSysConfigure gsc = SpringUtils.getBean(GetSysConfigure.class);
				EColumnAuthority eca = EColumnAuthority.getEColumnAuthority(authCode);
				if (eca == null) {
						throw new CommonException("-60", "权限不能为空");
				}
				userColumnja = gsc.getAuthorityColumns(functionId, userId, eca);
				//region 获取子段选项组
		/*
		if (userColumnja != null && userColumnja.size() > 0) {
      int uclength = userColumnja.size();
      JSONObject tempColumnjo = null;
      JSONArray options = null;
      long optionId = 0;
      for (int i = 0; i < uclength; i++) {
        tempColumnjo = userColumnja.getJSONObject(i);
        if (tempColumnjo == null || tempColumnjo.isEmpty()) {
          continue;
        }

        optionId = tempColumnjo.getLongValue("sys_option_id");
        if (optionId <= 0) {
          continue;
        }

        options = gsc.getOptions(optionId);
        if (options == null) {
          options = new JSONArray();
        }
        tempColumnjo.put("option", options);
      }
    }
    */
				//endregion
				return userColumnja;
		}

		public JSONArray getUserSearchColumns(String function, long userId) {
				JSONArray searchColumnsja = null;

				long functionId = 0;
				JSONArray userColumnja = null;
				if (StringUtils.isNull(function)) {
						return userColumnja;
				}
				//判断是否是ID
				if (StringUtils.isDigital(function)) {
						functionId = Long.valueOf(function);
				} else {
						Function fun = functionManager.getByName(function);
						functionId = fun.getId();
				}
				GetSysConfigure gsc = SpringUtils.getBean(GetSysConfigure.class);

				searchColumnsja = gsc.getUserSearchColumns(functionId, userId);

				return searchColumnsja;
		}
}
